﻿using System;
using UnityEngine;

namespace TrueSync {

    /**
     *  @brief表示在连接到游戏的每台机器上模拟每个玩家的行为。
     */
    public abstract class TrueSyncBehaviour : MonoBehaviour, ITrueSyncBehaviourGamePlay, ITrueSyncBehaviourCallbacks {

        /**
         * @brief 连接到游戏的玩家数量。
         **/
        [HideInInspector]
        public int numberOfPlayers;

        /**
         *  @brief 所有者在初始球员名单上的索引。
         */
		public int ownerIndex = -1;

        /**
         *  @brief 关于此行为所有者的基本信息。
         */
        [HideInInspector]
        public TSPlayerInfo owner;

        /**
         *  @brief 本地玩家的基本信息。
         */
        [HideInInspector]
        public TSPlayerInfo localOwner;

        private TSTransform _tsTransform;

        /**
         *  @brief 返回附加的{@link tstrtransform}。
         */
        public TSTransform tsTransform {
            get {
                if (_tsTransform == null) {
                    _tsTransform = this.GetComponent<TSTransform>();
                }

                return _tsTransform;
            }
        }

        private TSTransform2D _tsTransform2D;

        /**
         *  @brief返回附加的{@link TSTransform2D}。
         */
        public TSTransform2D tsTransform2D {
            get {
                if (_tsTransform2D == null) {
                    _tsTransform2D = this.GetComponent<TSTransform2D>();
                }

                return _tsTransform2D;
            }
        }

        private TSRigidBody _tsRigidBody;

        /**
         *  @brief 返回附加的{@link TSRigidBody}。
         */
        public TSRigidBody tsRigidBody {
            get {
                if (_tsRigidBody == null) {
                    _tsRigidBody = this.GetComponent<TSRigidBody>();
                }

                return _tsRigidBody;
            }
        }

        private TSRigidBody2D _tsRigidBody2D;

        /**
         *  @brief 返回附加的{@link TSRigidBody2D}。
         */
        public TSRigidBody2D tsRigidBody2D {
            get {
                if (_tsRigidBody2D == null) {
                    _tsRigidBody2D = this.GetComponent<TSRigidBody2D>();
                }

                return _tsRigidBody2D;
            }
        }

        private TSCollider _tsCollider;

        /**
         *  @brief 返回附加的{@link TSCollider}。
         */
        public TSCollider tsCollider {
            get {
                if (_tsCollider == null) {
                    _tsCollider = this.GetComponent<TSCollider>();
                }

                return _tsCollider;
            }
        }

        private TSCollider2D _tsCollider2D;

        /**
         *  @brief 返回附加的{@link TSCollider2D}。
         */
        public TSCollider2D tsCollider2D {
            get {
                if (_tsCollider2D == null) {
                    _tsCollider2D = this.GetComponent<TSCollider2D>();
                }

                return _tsCollider2D;
            }
        }

        /**
         * @brief 它不会被{@link TrueSyncBehaviour}的实例调用。
         **/
        public void SetGameInfo(TSPlayerInfo localOwner, int numberOfPlayers) {}

        /**
         * @brief 当对象变为活动状态时调用一次。
         **/
        public virtual void OnSyncedStart() { }

        /**
         * @brief 对象激活后，在本地玩家拥有的实例上调用一次。
         **/
        public virtual void OnSyncedStartLocalPlayer() { }

        /**
         * @brief 当游戏暂停时调用。
         **/
        public virtual void OnGamePaused() { }

        /**
         * @brief 当游戏未暂停时调用。
         **/
        public virtual void OnGameUnPaused() { }

        /**
         * @brief 游戏结束时调用。
         **/
        public virtual void OnGameEnded() { }

        /**
         *  @brief 在{@link #OnSyncedUpdate}之前调用。
         *  
         *  Called 每隔一帧锁步。
         */
        public virtual void OnPreSyncedUpdate() { }

        /**
         *  @brief 游戏更新在这里。
         *  
         *  Called 每隔一帧锁步。
         */
        public virtual void OnSyncedUpdate() { }

        /**
         *  @brief 获取本地玩家数据。
         *  
         *  Called 每隔一帧锁步。
         */
        public virtual void OnSyncedInput() { }

        /**
         * @brief 当玩家断开连接时调用回调。
         **/
        public virtual void OnPlayerDisconnection(int playerId) {}

    }

}